package myTeam;

import java.awt.Robot;
import java.io.Serializable;

import robocode.AdvancedRobot;

public class Predicao implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private double posXEnemy;
	private double posYEnemy;
	private double giroEnemy;
	private double distanciaEnemy;
	private double headingEnemy;
	private double enemySpeed;
	private long turnRate;
	private String name;

	public double getPosXEnemy() {
		return posXEnemy;
	}

	public void setPosXEnemy(double posXEnemy) {
		this.posXEnemy = posXEnemy;
	}

	public double getPosYEnemy() {
		return posYEnemy;
	}

	public void setPosYEnemy(double posYEnemy) {
		this.posYEnemy = posYEnemy;
	}

	public double getGiroEnemy() {
		return giroEnemy;
	}

	public void setGiroEnemy(double giroEnemy) {
		this.giroEnemy = giroEnemy;
	}

	public double getHeadingEnemy() {
		return headingEnemy;
	}

	public void setHeadingEnemy(double headingEnemy) {
		this.headingEnemy = headingEnemy;
	}

	public double getEnemySpeed() {
		return enemySpeed;
	}

	public void setEnemySpeed(double enemySpeed) {
		this.enemySpeed = enemySpeed;
	}

	public long getTurnRate() {
		return turnRate;
	}

	public void setTurnRate(long turnRate) {
		this.turnRate = turnRate;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Predicao() {
		// TODO Auto-generated constructor stub
	}

	public Predicao(double posXEnemy, double posYEnemy, double giroEnemy,
			double headingEnemy, double enemySpeed, long turnRate, String name) {
		// TODO Auto-generated constructor stub
		this.posXEnemy = posXEnemy;
		this.posYEnemy = posYEnemy;
		this.giroEnemy = giroEnemy;
		this.headingEnemy = headingEnemy;
		this.enemySpeed = enemySpeed;
		this.turnRate = turnRate;
		this.name = name;
	}

	public double mirar(double posX, double posY) {
		double deslocamentoRadar;
		// seta a quantidade necessária para rotação do radar de acordo com a
		// posicao do inimigo
		deslocamentoRadar = headingEnemy
				- absbearing(posX, posY, advinharXEnemy(), advinharYEnemy());

		if (deslocamentoRadar < 0) {
			deslocamentoRadar -= Math.PI / 8;
		} else {
			deslocamentoRadar += Math.PI / 8;
		}

		// gira o radar
		deslocamentoRadar = normalizarAngulo(deslocamentoRadar);
		return deslocamentoRadar;
	}

	public double advinharXEnemy() {
		return posXEnemy + (enemySpeed * Math.sin(headingEnemy + turnRate));
	}

	public double advinharYEnemy() {
		return posYEnemy + (enemySpeed * Math.cos(headingEnemy + turnRate));
	}

	public long getTurnRate(double enemyHeading, double lastEnemyHeading,
			long timeNow, long timeBefore) {
		return (long) ((enemyHeading - lastEnemyHeading) / (timeNow - timeBefore));
	}

	public double absbearing(double x1, double y1, double x2, double y2) {
		double xo = x2 - x1;
		double yo = y2 - y1;
		double h = getDistanciaEuclidiana(x1, y1, x2, y2);
		if (xo > 0 && yo > 0) {
			return Math.asin(xo / h);
		}
		if (xo > 0 && yo < 0) {
			return Math.PI - Math.asin(xo / h);
		}
		if (xo < 0 && yo < 0) {
			return Math.PI + Math.asin(-xo / h);
		}
		if (xo < 0 && yo > 0) {
			return 2.0 * Math.PI - Math.asin(-xo / h);
		}
		return 0;
	}

	public double getDistanciaEuclidiana(double x1, double y1, double x2,
			double y2) {
		double xo = x2 - x1;
		double yo = y2 - y1;
		double h = Math.sqrt(xo * xo + yo * yo);
		return h;
	}

	public double getDistanciaEuclidiana(double x1, double y1) {
		double xo = posXEnemy - x1;
		double yo = posYEnemy - y1;
		double h = Math.sqrt(xo * xo + yo * yo);
		return h;
	}

	public double normalizarAngulo(double ang) {
		if (ang > Math.PI)
			ang -= 2 * Math.PI;
		if (ang < -Math.PI)
			ang += 2 * Math.PI;
		return ang;
	}

	public double getDistance() {
		return distanciaEnemy;
	}

	public double getEnemyBearing() {

		return giroEnemy;
	}

	// normaliza o giro
	public double normaliseBearingRadians(double ang) {
		if (ang > Math.PI)
			ang -= 2 * Math.PI;
		if (ang < -Math.PI)
			ang += 2 * Math.PI;
		return ang;
	}

	public double absbearing(double x1, double y1) {
		double xo = advinharXEnemy()  - x1;
		double yo = advinharYEnemy()  - y1;
		double h = getDistanciaEuclidiana(x1, y1);
		if (xo > 0 && yo > 0) {
			return Math.asin(xo / h);
		}
		if (xo > 0 && yo < 0) {
			return Math.PI - Math.asin(xo / h);
		}
		if (xo < 0 && yo < 0) {
			return Math.PI + Math.asin(-xo / h);
		}
		if (xo < 0 && yo > 0) {
			return 2.0 * Math.PI - Math.asin(-xo / h);
		}
		return 0;
	}

	public double getDistanciaEuclidiana(AdvancedRobot r) {
		double xo = posXEnemy - r.getX();
		double yo = posYEnemy - r.getY();
		double h = Math.sqrt(xo * xo + yo * yo);
		return h;
	}

}
